import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import { UserInputError } from 'apollo-server';

import { CreateRoleDTO } from './dto/create-role.dto';
import { UpdateRoleDTO } from './dto/update-role.dto';
import { prisma } from '../../generated/prisma-client/sys';
import { QueryPipe } from 'src/common/pipe/query.pipe';
import { QueryDTO } from 'src/common/dto/query.dto';
import { Authorities } from 'src/common/decorator/authorities.decorator';

@Resolver('SysRole')
export class SysRoleResolver {
  @Query('querySysRoles')
  @Authorities('AUTH_SYS_ROLE_VIEW')
  async querySysRoles(
    @Args('query', QueryPipe) { first, skip, orderBy }: QueryDTO,
  ) {
    const fragment = `
      fragment RolesWithAuthorities on SysRole {
        id
        name
        description
        dateCreated
        dateUpdated
        authorities {
          id
          description
        }
      }
    `;

    const items = await prisma
      .sysRoles({
        first,
        skip,
        orderBy,
      })
      .$fragment(fragment);

    const count: number = await prisma
      .sysRolesConnection()
      .aggregate()
      .count();
    return { items, count };
  }

  @Query('sysRoles')
  @Authorities('AUTH_SYS_USER_CREATE', 'AUTH_SYS_USER_UPDATE')
  async sysRoles() {
    const fragment = `
      fragment RolesSelect on SysRole {
        id
        description
      }
    `;
    return await prisma.sysRoles().$fragment(fragment);
  }

  @Query('sysRole')
  async sysRole(
    @Args('id')
    id: string,
  ) {
    return prisma.sysRole({ id });
  }

  @Mutation('createSysRole')
  @Authorities('AUTH_SYS_ROLE_CREATE')
  async createSysRole(
    @Args('role')
    { authorityIds, ...data }: CreateRoleDTO,
  ) {
    const tmp = await prisma.sysRole({ name: data.name });
    if (tmp) {
      throw new UserInputError('角色已存在！', { property: 'name' });
    }

    return await prisma.createSysRole({
      ...data,
      authorities: {
        connect: authorityIds.map(id => ({
          id,
        })),
      },
    });
  }

  @Mutation('updateSysRole')
  @Authorities('AUTH_SYS_ROLE_UPDATE')
  async updateSysRole(
    @Args('role')
    { id, authorityIds, ...data }: UpdateRoleDTO,
  ) {
    return await prisma.updateSysRole({
      where: { id },
      data: {
        ...data,
        authorities: {
          set: authorityIds.map(item => ({
            id: item,
          })),
        },
      },
    });
  }

  @Mutation('deleteSysRoles')
  @Authorities('AUTH_SYS_ROLE_DELETE')
  async deleteSysRoles(
    @Args('ids')
    ids: string[],
  ) {
    return await prisma.deleteManySysRoles({ id_in: [...ids] });
  }
}
